Create all Response Curves - RLM
start_time <- Sys.time()
fits.non.search.RLM <- lapply(
1:length(df_names),
function(i) {
model_wrapper_function2(df = df_names[i][[1]])
}
)
end_time <- Sys.time()
combined_rlm_time <- start_time - end_time
best.ind.non.search.RLM <- lapply(
1:length(df_names),
function(i) {
lapply(1:length(df_names[i][[1]]), best_ind_function,df = fits.non.search.RLM[i][[1]],
df2 = df_names[i][[1]])
}
)
coef.non.search.RLM <- lapply(
1:length(df_names),
function (i){
best.ind.non.search.RLM[i][[1]] %>% bind_rows
}
) %>%
bind_rows() %>%
as.data.frame() %>%
mutate(
cost_p2 = 0,
lambda = 0,
alpha = 0,
powers2 = 0
) %>%
select(one_of(colnames(coef.2_matrix)))
best.fit.non.search.RLM <- lapply(1:length(df_names),
function(j) {
lapply(1:length(best.ind.non.search.RLM[[j]]),
function(i){
best.ind.non.search.RLM[j][[1]][i] %>%
set_names(nm = best.ind.non.search.RLM[j][[1]][[i]]["model"])
}
)
}
)
-combined_ridge_time+combined_rlm_time
Time difference of 32.768 mins
graph.list.rlm <- lapply(1:length(df_names),
function(i){
lapply(1:length(best.fit.non.search.RLM[i][[1]]), graphing_function_rlm, df1= best.fit.non.search.RLM[i],df2 = df_names[i])
}
)
graph.list.RIDGE_LASSO <- lapply(1:length(df_names),
function(i){
lapply(1:length(best.fit.non.search.RIDGE_LASSO[i][[1]]), graphing_function_elasticnet, df1= best.fit.non.search.RIDGE_LASSO[i],df2 = df_names[i])
}
)
Export all Plots
folder_name1 <- paste0("Output/", "outputfiles_", Sys.Date(), "_", "RLM", "/")
dir.create(folder_name1) # it will throw a warning if folder exists
Warning in dir.create(folder_name1) :
'Output\outputfiles_2022-11-08_RLM' already exists
lapply(1:length(df_names),
function(j) {
lapply(1:length(df_names[[j]]),export_rplots_function2,starting_name = "Non_Search_",folder_name = folder_name1,df_list = df_names[[j]],graphing_list = graph.list.rlm[j][[1]])
}
)
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
[[1]]
[[1]][[1]]
[1] "Output/outputfiles_2022-11-08_RLM/Non_Search_Chrome_All_Channel.png"
[[1]][[2]]
[1] "Output/outputfiles_2022-11-08_RLM/Non_Search_Chrome_non-REMK.png"
[[1]][[3]]
[1] "Output/outputfiles_2022-11-08_RLM/Non_Search_Chrome_REMK.png"
[[2]]
[[2]][[1]]
[1] "Output/outputfiles_2022-11-08_RLM/Non_Search_Cloud_Cloud_-_All_Channel.png"
[[3]]
[[3]][[1]]
[1] "Output/outputfiles_2022-11-08_RLM/Non_Search_DSM_EMEA__DISCOVERY.png"
[[3]][[2]]
[1] "Output/outputfiles_2022-11-08_RLM/Non_Search_DSM_EMEA__DISPLAY.png"
[[3]][[3]]
[1] "Output/outputfiles_2022-11-08_RLM/Non_Search_DSM_EMEA__YOUTUBE.png"
[[3]][[4]]
[1] "Output/outputfiles_2022-11-08_RLM/Non_Search_DSM_NA__DISCOVERY.png"
[[3]][[5]]
[1] "Output/outputfiles_2022-11-08_RLM/Non_Search_DSM_NA__DISPLAY.png"
[[3]][[6]]
[1] "Output/outputfiles_2022-11-08_RLM/Non_Search_DSM_NA__YOUTUBE.png"
[[4]]
[[4]][[1]]
[1] "Output/outputfiles_2022-11-08_RLM/Non_Search_Google_Fi_DISCOVERY.png"
[[4]][[2]]
[1] "Output/outputfiles_2022-11-08_RLM/Non_Search_Google_Fi_DISPLAY.png"
[[4]][[3]]
[1] "Output/outputfiles_2022-11-08_RLM/Non_Search_Google_Fi_YOUTUBE.png"
[[5]]
[[5]][[1]]
[1] "Output/outputfiles_2022-11-08_RLM/Non_Search_Pixel_Pixel_-_All_Channel.png"
[[6]]
[[6]][[1]]
[1] "Output/outputfiles_2022-11-08_RLM/Non_Search_SMB_DISCOVERY.png"
[[6]][[2]]
[1] "Output/outputfiles_2022-11-08_RLM/Non_Search_SMB_DISPLAY.png"
[[6]][[3]]
[1] "Output/outputfiles_2022-11-08_RLM/Non_Search_SMB_YOUTUBE.png"
[[7]]
[[7]][[1]]
[1] "Output/outputfiles_2022-11-08_RLM/Non_Search_SMB-QLead_SMB_-_Q-Lead.png"
[[8]]
[[8]][[1]]
[1] "Output/outputfiles_2022-11-08_RLM/Non_Search_YouTube_APAC.png"
[[8]][[2]]
[1] "Output/outputfiles_2022-11-08_RLM/Non_Search_YouTube_EMEA.png"
[[8]][[3]]
[1] "Output/outputfiles_2022-11-08_RLM/Non_Search_YouTube_NA.png"

folder_name2 <- paste0("Output/", "outputfiles_", Sys.Date(), "_", "ElasticNet", "/")
dir.create(folder_name2) # it will throw a warning if folder exists
Warning in dir.create(folder_name2) :
'Output\outputfiles_2022-11-08_ElasticNet' already exists
lapply(1:length(df_names),
function(j) {
lapply(1:length(df_names[[j]]),export_rplots_function2,starting_name = "Non_Search_",folder_name = folder_name2,df_list = df_names[[j]],graphing_list = graph.list.RIDGE_LASSO[j][[1]])
}
)
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
Saving 18.8 x 12.5 in image
[[1]]
[[1]][[1]]
[1] "Output/outputfiles_2022-11-08_ElasticNet/Non_Search_Chrome_All_Channel.png"
[[1]][[2]]
[1] "Output/outputfiles_2022-11-08_ElasticNet/Non_Search_Chrome_non-REMK.png"
[[1]][[3]]
[1] "Output/outputfiles_2022-11-08_ElasticNet/Non_Search_Chrome_REMK.png"
[[2]]
[[2]][[1]]
[1] "Output/outputfiles_2022-11-08_ElasticNet/Non_Search_Cloud_Cloud_-_All_Channel.png"
[[3]]
[[3]][[1]]
[1] "Output/outputfiles_2022-11-08_ElasticNet/Non_Search_DSM_EMEA__DISCOVERY.png"
[[3]][[2]]
[1] "Output/outputfiles_2022-11-08_ElasticNet/Non_Search_DSM_EMEA__DISPLAY.png"
[[3]][[3]]
[1] "Output/outputfiles_2022-11-08_ElasticNet/Non_Search_DSM_EMEA__YOUTUBE.png"
[[3]][[4]]
[1] "Output/outputfiles_2022-11-08_ElasticNet/Non_Search_DSM_NA__DISCOVERY.png"
[[3]][[5]]
[1] "Output/outputfiles_2022-11-08_ElasticNet/Non_Search_DSM_NA__DISPLAY.png"
[[3]][[6]]
[1] "Output/outputfiles_2022-11-08_ElasticNet/Non_Search_DSM_NA__YOUTUBE.png"
[[4]]
[[4]][[1]]
[1] "Output/outputfiles_2022-11-08_ElasticNet/Non_Search_Google_Fi_DISCOVERY.png"
[[4]][[2]]
[1] "Output/outputfiles_2022-11-08_ElasticNet/Non_Search_Google_Fi_DISPLAY.png"
[[4]][[3]]
[1] "Output/outputfiles_2022-11-08_ElasticNet/Non_Search_Google_Fi_YOUTUBE.png"
[[5]]
[[5]][[1]]
[1] "Output/outputfiles_2022-11-08_ElasticNet/Non_Search_Pixel_Pixel_-_All_Channel.png"
[[6]]
[[6]][[1]]
[1] "Output/outputfiles_2022-11-08_ElasticNet/Non_Search_SMB_DISCOVERY.png"
[[6]][[2]]
[1] "Output/outputfiles_2022-11-08_ElasticNet/Non_Search_SMB_DISPLAY.png"
[[6]][[3]]
[1] "Output/outputfiles_2022-11-08_ElasticNet/Non_Search_SMB_YOUTUBE.png"
[[7]]
[[7]][[1]]
[1] "Output/outputfiles_2022-11-08_ElasticNet/Non_Search_SMB-QLead_SMB_-_Q-Lead.png"
[[8]]
[[8]][[1]]
[1] "Output/outputfiles_2022-11-08_ElasticNet/Non_Search_YouTube_APAC.png"
[[8]][[2]]
[1] "Output/outputfiles_2022-11-08_ElasticNet/Non_Search_YouTube_EMEA.png"
[[8]][[3]]
[1] "Output/outputfiles_2022-11-08_ElasticNet/Non_Search_YouTube_NA.png"
Show Graphs
lapply(1:length(df_names),
function(j){
subplot(graph.list.rlm[j][[1]], nrows = length(graph.list.rlm[j][[1]]))
}
)
[[1]]
[[2]]
[[3]]
[[4]]
[[5]]
[[6]]
[[7]]
[[8]]
lapply(1:length(df_names),
function(i){
#p1 = graph_names[i][[1]]
do.call(grid.arrange,graph.list.rlm[i][[1]])
#return(grid.arrange(grobs = p1))
}
)
[[1]]
TableGrob (3 x 1) "arrange": 3 grobs
[[2]]
TableGrob (1 x 1) "arrange": 1 grobs
[[3]]
TableGrob (3 x 2) "arrange": 6 grobs
[[4]]
TableGrob (3 x 1) "arrange": 3 grobs
[[5]]
TableGrob (1 x 1) "arrange": 1 grobs
[[6]]
TableGrob (3 x 1) "arrange": 3 grobs
[[7]]
TableGrob (1 x 1) "arrange": 1 grobs
[[8]]
TableGrob (3 x 1) "arrange": 3 grobs
NA








lapply(1:length(df_names),
function(j){
subplot(graph.list.RIDGE_LASSO[j][[1]], nrows = length(graph.list.RIDGE_LASSO[j][[1]]))
}
)
[[1]]
[[2]]
[[3]]
[[4]]
[[5]]
[[6]]
[[7]]
[[8]]
lapply(1:length(df_names),
function(i){
#p1 = graph_names[i][[1]]
do.call(grid.arrange,graph.list.RIDGE_LASSO[i][[1]])
#return(grid.arrange(grobs = p1))
}
)
[[1]]
TableGrob (3 x 1) "arrange": 3 grobs
[[2]]
TableGrob (1 x 1) "arrange": 1 grobs
[[3]]
TableGrob (3 x 2) "arrange": 6 grobs
[[4]]
TableGrob (3 x 1) "arrange": 3 grobs
[[5]]
TableGrob (1 x 1) "arrange": 1 grobs
[[6]]
TableGrob (3 x 1) "arrange": 3 grobs
[[7]]
TableGrob (1 x 1) "arrange": 1 grobs
[[8]]
TableGrob (3 x 1) "arrange": 3 grobs
NA








LS0tDQp0aXRsZTogIjAzX0NMU19TcGVuZF9SZXNwb25zZV9DdXJ2ZXNfTm9fUG9seSINCmF1dGhvcjogIkVzc2VuY2UgR2xvYmFsIEFkdmFuY2VkIEFuYWx5dGljcyBUZWFtIg0KZGF0ZTogImByIFN5cy5EYXRlKClgIg0Kb3V0cHV0Og0KICBodG1sX25vdGVib29rOg0KICAgIHRvYzogeWVzDQogICAgdG9jX2Zsb2F0OiB5ZXMNCiAgICBudW1iZXJfc2VjdGlvbnM6IG5vDQogICAgdGhlbWU6IGNlcnVsZWFuDQogICAgaGlnaGxpZ2h0OiB6ZW5idXJuDQogICAgZGZfcHJpbnQ6IHBhZ2VkDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpDQpvcHRpb25zKGtuaXRyLnRhYmxlLmZvcm1hdCA9ICJodG1sIikNCm9wdGlvbnMoZGlnaXRzID0gNSkNCm9wdGlvbnMoc2NpcGVuID0gMTAwKQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KHRpZHkub3B0cyA9IGxpc3Qod2lkdGguY3V0b2ZmID0gODApLCB0aWR5ID0gVFJVRSkNCmtuaXRyOjpvcHRzX2NodW5rJHNldChmaWcud2lkdGggPSAxNSkNCmtuaXRyOjpvcHRzX2NodW5rJHNldChmaWcuaGVpZ2h0ID0gMTApDQojIGluc3RhbGwucGFja2FnZXMoInBhY21hbiIpDQpsaWJyYXJ5KHBhY21hbikgIyBmb3IgcXVpY2sgbG9hZC9pbnN0YWxsIG9mIHBhY2thZ2VzDQpwX2xvYWQoZHBseXIsIHJlYWRyLCB0aWR5dmVyc2UsIHJldGljdWxhdGUsIGx1YnJpZGF0ZSwgamFuaXRvciwgc3FsZGYsIGdvb2dsZXNoZWV0czQpDQpwX2xvYWQoc2tpbXIsIHNwbGl0c3RhY2tzaGFwZSwgc3RyaW5nciwgcnFkYXRhdGFibGUpDQpwX2xvYWQobW9tZW50cykNCnBfbG9hZChrYWJsZUV4dHJhKQ0KcF9sb2FkKGdncGxvdDIsIHBsb3RseSwgZWNoYXJ0czRyLCBnZ3B1YnIsIGZvcmNhdHMsIHNjYWxlcywgUkNvbG9yQnJld2VyLGdyaWRFeHRyYSkNCnBfbG9hZChnZ3RoZW1lcykNCnBfbG9hZChjYXJldCwgcmVjaXBlcykNCnBfbG9hZChnbG1uZXQpDQpwX2xvYWQoZWxhc3RpY25ldCkNCnBfbG9hZChNZXRyaWNzKQ0KcF9sb2FkKGZhc3REdW1taWVzKQ0KcF9sb2FkKGJyb29tKQ0KcF9sb2FkKGh0bWx3aWRnZXRzKQ0KcF9sb2FkKHNvbGl0dWRlKQ0KcF9sb2FkKG1sYmVuY2gpDQpwX2xvYWQodXdvdCkNCmBgYA0KDQojIFVzZSBEYXRhc2V0IGNyZWF0ZWQgZnJvbSAwMl9DTFNfRGF0YV9TdW1tYXJ5XzIwMjJfMDkxNF9EYXRhX0FuYWx5c2lzIEZpbGUNCg0KIyMgTG9hZGluZyBEYXRhDQoNCiMjIyBMb2FkIEdvb2dsZSBTaGVldA0KDQpgYGB7cn0NCkZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlIDwtIHJlYWRfc2hlZXQoDQogICJodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9zcHJlYWRzaGVldHMvZC8xTjQ4clRlcTdtZDB2OHc4cEdfOFhJaXVhcFBIUUFlTzVXb1dJQjNlYWNlSS9lZGl0I2dpZD0xNDQ5MzUxMzc3IiwNCiAgc2hlZXQgPSAiRmluYWxEYXRhc2V0XzIwMjJfVXBkYXRlIg0KKSAlPiUNCiAgbXV0YXRlKA0KICAgIFNpZ25pZmljYW50X1NwZW5kID0NCiAgICAgIGFzLm51bWVyaWMoDQogICAgICAgIGNhc2Vfd2hlbigNCiAgICAgICAgICBwcm9iYWJpbGl0eV9vZl9saWZ0ID49IDAuOSB+IDEsDQogICAgICAgICAgVFJVRSB+IDANCiAgICAgICAgKQ0KICAgICAgKSwNCiAgICBjb3VudHJ5ID0gY2FzZV93aGVuKA0KICAgICAgY291bnRyeSA9PSAiTkEiIH4gIlVTIiwNCiAgICAgIFRSVUUgfiBjb3VudHJ5DQogICAgKSwNCiAgICByZWdpb25fdjIgPSBjYXNlX3doZW4oDQogICAgICBjb3VudHJ5ID09ICJVUyIgfiAiTkEiLA0KICAgICAgY291bnRyeSA9PSAiQ0EiIH4gIk5BIiwNCiAgICAgIGNvdW50cnkgPT0gIlVTICsgQ0EiIH4gIk5BIiwNCiAgICAgIFRSVUUgfiByZWdpb24NCiAgICApDQogICkgJT4lDQogIGZpbHRlcihjaGFubmVsICE9ICJTZWFyY2giKSAlPiUNCiAgIyBmaWx0ZXIgb3V0IHN0dWRpZXMgd2l0aG91dCByZXBvcnRlZCBsaWZ0cw0KICBmaWx0ZXIoZXhwb3NlZCAhPSAtMSkgJT4lDQogICMgZmlsdGVyIG91dCBnb29nbGUgcGF5IHN0dWR5DQogIGZpbHRlcihzdHVkeV9pZCAhPSAiMTQ5MTQyMjE3IikgJT4lDQogICMgZmlsdGVyIG91dCB2ZXJ5IG5lZ2F0aXZlIGFic29sdXRlIGxpZnRzDQogIGZpbHRlcihhYnNvbHV0ZV9saWZ0ID4gLTEwMDApICU+JQ0KICBtdXRhdGUoDQogICAgcGEgPSBjYXNlX3doZW4oDQogICAgICBwYSA9PSAiR29vZ2xlIEFkcyIgfiAiU01CIiwgIyBTdGVwIDENCiAgICAgIHBhID09ICJZb3VUdWJlIiAmIGNvbnZlcnNpb24gIT0gIlR5cGUgMjU2NTIyOTQyIChbTUNDXSBZb3VUdWJlIFRWIC0gV2ViIC0gVHJpYWwgU3RhcnQpIiB+ICJZVE1QIiwgIyBTdGVwIDINCiAgICAgIHBhID09ICJZb3VUdWJlIFByZW1pdW0iIH4gIllUTVAiLCAjIFN0ZXAgMg0KICAgICAgY29udmVyc2lvbiA9PSAiVHlwZSAyNTY1MjI5NDIgKFtNQ0NdIFlvdVR1YmUgVFYgLSBXZWIgLSBUcmlhbCBTdGFydCkiIH4gIllvdVR1YmUgVFYiLCAjIFN0ZXAgMg0KICAgICAgcGEgPT0gIkNsb3VkIiAmIGNvbnZlcnNpb24gIT0gIlR5cGUgMTQyNTc4MDMgKEVudGVycHJpc2UgLSBBcHBzIC0gU2lnbnVwIENvbmZpcm0gLSBVbmlxdWUpIiB+ICJDbG91ZCBXb3Jrc3BhY2UiLCAjIFN0ZXAgMw0KICAgICAgcGEgPT0gIkNsb3VkIiAmIGNvbnZlcnNpb24gPT0gIlR5cGUgMTQyNTc4MDMgKEVudGVycHJpc2UgLSBBcHBzIC0gU2lnbnVwIENvbmZpcm0gLSBVbmlxdWUpIiB+ICJDbG91ZCBHQ1AiLCAjIFN0ZXAgMw0KICAgICAgcGEgPT0gIlByb2plY3QgRmkiIH4gIkdvb2dsZSBGaSIsICMgU3RlcCA0DQogICAgICBwYSA9PSAiR29vZ2xlIENocm9tZSIgfiAiQ2hyb21lIiwNCiAgICAgIFRSVUUgfiBwYQ0KICAgICkNCiAgKSAlPiUNCiAgbXV0YXRlKA0KICAgIHBhcnNlZF90eXBlID0gcGFyc2VfbnVtYmVyKGNvbnZlcnNpb24pLA0KICAgIGdyb3VwZWRfY29udmVyc2lvbiA9IGNhc2Vfd2hlbigNCiAgICAgIGNvbnZlcnNpb24gJWluJSBjKCJDaHJvbWVib29rIE1pY3Jvc2l0ZSBSZWZlcnJhbCBDbGlja3MgUTQgMjAxNSIsICJUeXBlIDI1MTQyMjcyOSAoQ2hyb21lYm9va3MgTWljcm9zaXRlIFJlZmVycmFsIENsaWNrcyAoUTQgMjAxNykpIikgfiAiQ2hyb21lYm9vayBSZWZlcnJhbHMiLA0KICAgICAgY29udmVyc2lvbiAlaW4lIGMoIkRlc2t0b3AgRG93bmxvYWRzIiwgIlR5cGUgMTE1NDE1NDcgKERlc2t0b3AgRG93bmxvYWQpIikgfg0KICAgICAgICAiRGVza3RvcCBEb3dubG9hZHMiLA0KICAgICAgcGEgPT0gIlBpeGVsIiB+ICJNb2JpbGUgQ29udmVyc2lvbnMiLA0KICAgICAgcGEgPT0gIkRTTSIgfiAiTm9uLU1vYmlsZSBEZXZpY2UgQ29udmVyc2lvbnMiLA0KICAgICAgY29udmVyc2lvbiA9PSAiVHlwZSAzMDI5ODI5NTQgKExlbmEgLSBQIExlYWQpIiB+ICJMZW5hIFAgTGVhZCIsDQogICAgICBjb252ZXJzaW9uID09ICJUeXBlIDI4ODM0NzAwOCAoTEVOQSAtIEIgTGVhZCkiIH4gIkxlbmEgQiBMZWFkIiwNCiAgICAgIGNvbnZlcnNpb24gPT0gIlR5cGUgMjg4Njk3NjUzIChMRU5BIC0gUSBMZWFkKSIgfiAiTGVuYSBRIExlYWQiLA0KICAgICAgcGFyc2VkX3R5cGUgJWluJSBjKDE4MTI4Mzk5MywgODU1NTA4Njg2KSB+ICJXb3Jrc3BhY2UgRnJlZSBUcmlhbCBTdGFydCIsDQogICAgICBwYXJzZWRfdHlwZSA9PSAzMzA3NTU2NDEgfiAiTWljcm9zaXRlIENvbnZlcnNpb25zIiwNCiAgICAgIHBhcnNlZF90eXBlID09IDE0MjU3ODAzIH4gIkVudGVycHJpc2UgU2lnbnVwcyIsDQogICAgICBwYXJzZWRfdHlwZSA9PSAyODk2ODA3MTIgfiAiR29vZ2xlKGlPcykgRmlyc3QgT3BlbiIsDQogICAgICBwYXJzZWRfdHlwZSA9PSAyNTY1MjI5NDIgfiAiWW91VHViZSBUViAtIFdlYiAtIFRyaWFsIFN0YXJ0IiwNCiAgICAgIHBhcnNlZF90eXBlICVpbiUgYyg0NTIzOTE1MzQsIDIyMTQ5NzgzMywgMjc3MTUwMDc0KSB+ICJUcmlhbCBTaWdudXBzIENvbXBsZXRlIiwNCiAgICAgIFRSVUUgfiBjb252ZXJzaW9uDQogICAgKSwNCiAgICBwYSA9IGNhc2Vfd2hlbigNCiAgICAgIGNvbnZlcnNpb24gPT0gIlR5cGUgMjg4Njk3NjUzIChMRU5BIC0gUSBMZWFkKSIgfiAiU01CLVFMZWFkIiwNCiAgICAgIFRSVUUgfiBwYQ0KICAgICkNCiAgKSAlPiUNCiAgZmlsdGVyKGFic29sdXRlX2xpZnQgPiAwKQ0KDQoNCiMgYWxsLmVxdWFsKEZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlLEZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF92MykNCmBgYA0KDQojIENyZWF0ZSBBbGwgUmVzcG9uc2UgQ3VydmVzIG9ubHkgbm9ybWFsIHBvd2Vycw0KDQojIyBGb2xkZXIgZm9yIGFsbCBPdXRwdXQgYW5kIHNjcmlwdHMNCg0KYGBge3J9DQpmb2xkZXJfbmFtZSA8LSBwYXN0ZTAoIk91dHB1dC8iLCAib3V0cHV0ZmlsZXNfIiwgU3lzLkRhdGUoKSwgIl8iLCAiUnVuMSIsICIvIikNCmRpci5jcmVhdGUoZm9sZGVyX25hbWUpICMgaXQgd2lsbCB0aHJvdyBhIHdhcm5pbmcgaWYgZm9sZGVyIGV4aXN0cw0KDQojIGZpbGUuc291cmNlczIgPC0gbGlzdC5maWxlcyhwYXRoID0gIk91dHB1dC9vdXRwdXRmaWxlc18yMDIyLTEwLTE0X1J1bjEvLyIsIHBhdHRlcm4gPSIuaHRtbHwucG5nIiwgZnVsbC5uYW1lcyA9IFRSVUUpDQpmaWxlLnNvdXJjZXMgPC0gbGlzdC5maWxlcyhwYXRoID0gIlJTY3JpcHRzLyIsIHBhdHRlcm4gPSAiKi5SIiwgZnVsbC5uYW1lcyA9IFRSVUUpDQpzYXBwbHkoZmlsZS5zb3VyY2VzLCBzb3VyY2UsIC5HbG9iYWxFbnYpDQpgYGANCg0KIyMgQ2hlY2sgcGFyYW1ldGVycw0KDQpgYGB7cn0NCg0KIyMjIHBvd2VycyB0byB0cnkNCnBvd2VycyA8LSBzZXEoMC4xLCAwLjksIGJ5ID0gMC4wMSkNCnBvd2VyczIgPC0gMQ0KDQojIyMgUG93ZXJzIHRvIFRyeQ0KI3Bvd2VycyA8LSBzZXEoMC4xLCAwLjksIGJ5ID0gMC4wMSkNCiNwb3dlcnMyIDwtc2VxKDEuNSwzLCBieSA9IDAuMjUpDQoNCg0KIyMjIExhbWJkYSBwYXJhbWV0ZXJzDQpwYXJhbWV0ZXJzIDwtIGMoDQogICMgIHNlcSgwLjEsIDIsIGJ5ID0wLjEpICwgIHNlcSgyLCA1LCAwLjUpICwNCiAgc2VxKDUsIDI5LCAxKQ0KICAsc2VxKDMwLCAxMDIsIDQpDQogICxzZXEoMTEwLCAxMDAwLCAxNSkNCiAgLHNlcSgxMDAwLCAxMDAyMCwgNTAwKQ0KKQ0KDQojIyMgZWxhc3RpY25ldCBwYXJhbWV0ZXJzDQphbHBoYV9wYXJhbWV0ZXJzIDwtIGMoc2VxKDAsIDEsIDAuMjUpKQ0KDQojIEZvciBUZXN0aW5nIFB1cnBvc2VzDQojYWxwaGFfcGFyYW1ldGVycyA8LSBjKHNlcSgxLCAxLCAxKSkNCg0KYGBgDQoNCiMjIFRlc3RpbmcgRGlmZmVyZW50IE1vZGVsIFR5cGVzDQoNCiMjIyBDaHJvbWUNCg0KIyMjIyBEYXRhIFJlYWRpbg0KDQpgYGB7cn0NCg0Kc3RhcnRfdGltZSA8LSBTeXMudGltZSgpDQoNCkZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX2Nocm9tZV9wcmUgPC0NCiAgRmluYWxfQ0xTXzIwMjJfU3R1ZHlfTGlzdF9Ob25fU2VhcmNoX21vZGVsX2ZpbGUgJT4lDQogIGZpbHRlcihwYSA9PSAiQ2hyb21lIikgJT4lDQogIG11dGF0ZSgNCiAgICBpZDIgPSByb3dfbnVtYmVyKCkNCiAgKQ0KDQpkZl90ZXN0IDwtDQogIEZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX2Nocm9tZV9wcmUgJT4lDQogIHNlbGVjdCgNCiAgICByZWdpb25fdjIsIGNvdW50cnksIGNoYW5uZWwsIHRhY3RpYywNCiAgICBjb3N0X3NwZW50X29uX2V4cG9zZWRfZ3JvdXA6YWJzb2x1dGVfbGlmdA0KICApDQoNCmlzb19jaHJvbWUgPC0gaXNvbGF0aW9uRm9yZXN0JG5ldyhzYW1wbGVfc2l6ZSA9IG5yb3coZGZfdGVzdCksIG51bV90cmVlcyA9IDEwMDAwLCBzZWVkID0gMTE1MykNCg0KaXNvX2Nocm9tZSRmaXQoZGZfdGVzdCkNCg0Kc2NvcmVzX3RyYWluIDwtIGRmX3Rlc3QgJT4lDQogIGlzb19jaHJvbWUkcHJlZGljdCgpICU+JQ0KICBhcnJhbmdlKGRlc2MoYW5vbWFseV9zY29yZSkpDQoNCkZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX2Nocm9tZV9wcmUyIDwtDQogIEZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX2Nocm9tZV9wcmUgJT4lDQogIGxlZnRfam9pbihzY29yZXNfdHJhaW4sIGJ5ID0gYygiaWQyIiA9ICJpZCIpKSAlPiUgDQogIGZpbHRlcihhdmVyYWdlX2RlcHRoID4gMykNCg0KDQpGaW5hbF9DTFNfMjAyMl9TdHVkeV9MaXN0X05vbl9TZWFyY2hfbW9kZWxfZmlsZV9jaHJvbWUgPC0NCiAgRmluYWxfQ0xTXzIwMjJfU3R1ZHlfTGlzdF9Ob25fU2VhcmNoX21vZGVsX2ZpbGVfY2hyb21lX3ByZTIgJT4lDQogIG5hbWVkX2dyb3VwX3NwbGl0KHRhY3RpYykNCmBgYA0KDQojIyMjIFJ1biBNb2RlbA0KDQpgYGB7ciwgd2FybmluZyA9IGZhbHNlfQ0KDQoNCmZpdHNfbm9uX3NlYXJjaF9jaHJvbWUgPC0gbW9kZWxfd3JhcHBlcl9mdW5jdGlvbihkZiA9IEZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX2Nocm9tZSxwb2x5X2luZCA9IDApDQoNCmJlc3RfaW5kX25vbl9zZWFyY2hfY2hyb21lIDwtIA0KICBsYXBwbHkoMTpsZW5ndGgoRmluYWxfQ0xTXzIwMjJfU3R1ZHlfTGlzdF9Ob25fU2VhcmNoX21vZGVsX2ZpbGVfY2hyb21lKSwgYmVzdF9pbmRfZnVuY3Rpb24sZGYgPSBmaXRzX25vbl9zZWFyY2hfY2hyb21lLA0KICAgICAgICAgZGYyID0gRmluYWxfQ0xTXzIwMjJfU3R1ZHlfTGlzdF9Ob25fU2VhcmNoX21vZGVsX2ZpbGVfY2hyb21lKSANCg0KY29lZl9ub25fc2VhcmNoX2Nocm9tZSA8LSBiZXN0X2luZF9ub25fc2VhcmNoX2Nocm9tZSAlPiUgYmluZF9yb3dzICNtYWtlIGEgbWF0cml4IG9mIGFsbCBjb2Vmcw0KDQpiZXN0X2ZpdF9ub25fc2VhcmNoX2Nocm9tZSA8LSBiZXN0X2luZF9ub25fc2VhcmNoX2Nocm9tZSAlPiUNCiAgc2V0X25hbWVzKG5hbWVzX2Z1bmN0aW9uKEZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX2Nocm9tZV9wcmUsIHRhY3RpYykpICANCmBgYA0KDQojIyMjIENyZWF0ZSBHcmFwaCBPYmplY3QNCg0KYGBge3J9DQpncmFwaF9saXN0X2Nocm9tZSA8LSBsYXBwbHkoMTpsZW5ndGgoYmVzdF9maXRfbm9uX3NlYXJjaF9jaHJvbWUpLCBncmFwaGluZ19mdW5jdGlvbjQsIGRmMSA9IGJlc3RfZml0X25vbl9zZWFyY2hfY2hyb21lLCBkZjIgPSBGaW5hbF9DTFNfMjAyMl9TdHVkeV9MaXN0X05vbl9TZWFyY2hfbW9kZWxfZmlsZV9jaHJvbWUpDQpgYGANCg0KYGBge3J9DQplbmRfdGltZSA8LSBTeXMudGltZSgpDQoNCnRpbWVfY2hyb21lID0gZW5kX3RpbWUgLSBzdGFydF90aW1lDQoNCnRpbWVfY2hyb21lDQpgYGANCg0KIyMjIENsb3VkDQoNCiMjIyMgRGF0YSBSZWFkaW4NCg0KYGBge3J9DQpzdGFydF90aW1lIDwtIFN5cy50aW1lKCkNCg0KRmluYWxfQ0xTXzIwMjJfU3R1ZHlfTGlzdF9Ob25fU2VhcmNoX21vZGVsX2ZpbGVfY2xvdWRfcHJlIDwtDQogIEZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlICU+JQ0KICBmaWx0ZXIocGEgJWluJSBjKCJDbG91ZCBHQ1AiLCAiQ2xvdWQgV29ya3NwYWNlIikpICU+JQ0KICBtdXRhdGUoDQogICAgcGEgPSAiQ2xvdWQiLA0KICAgIHBhMiA9ICJDbG91ZCAtIEFsbCBDaGFubmVsIg0KICApICU+JQ0KICBtdXRhdGUoDQogICAgaWQyID0gcm93X251bWJlcigpDQogICkNCg0KZGZfdGVzdCA8LQ0KICBGaW5hbF9DTFNfMjAyMl9TdHVkeV9MaXN0X05vbl9TZWFyY2hfbW9kZWxfZmlsZV9jbG91ZF9wcmUgJT4lDQogICMgc2VsZWN0KC1zdHVkeV9pZCwgLWlkMiwgLXJlZ2lvbiwgLXNjYWxpbmdfZmFjdG9yLCAtcXVhcnRlciwgLXBhLCAtc3R1ZHlfbmFtZSkNCiAgc2VsZWN0KA0KICAgIHJlZ2lvbl92MiwgY291bnRyeSwgY2hhbm5lbCwgdGFjdGljLA0KICAgICMgdHJlYXRtZW50X3VzZXJfY291bnQ6Y29udHJvbCwNCiAgICBjb3N0X3NwZW50X29uX2V4cG9zZWRfZ3JvdXA6YWJzb2x1dGVfbGlmdCwgcGFyc2VkX3R5cGUNCiAgKQ0KDQppc29fY2xvdWQgPC0gaXNvbGF0aW9uRm9yZXN0JG5ldyhzYW1wbGVfc2l6ZSA9IG5yb3coZGZfdGVzdCksIG51bV90cmVlcyA9IDEwMDAwLCBzZWVkID0gMTE1MykNCg0KaXNvX2Nsb3VkJGZpdChkZl90ZXN0KQ0KDQpzY29yZXNfdHJhaW4gPC0gZGZfdGVzdCAlPiUNCiAgaXNvX2Nsb3VkJHByZWRpY3QoKSAlPiUNCiAgYXJyYW5nZShkZXNjKGFub21hbHlfc2NvcmUpKQ0KDQpGaW5hbF9DTFNfMjAyMl9TdHVkeV9MaXN0X05vbl9TZWFyY2hfbW9kZWxfZmlsZV9jbG91ZF9wcmUyIDwtDQogIEZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX2Nsb3VkX3ByZSAlPiUNCiAgbGVmdF9qb2luKHNjb3Jlc190cmFpbiwgYnkgPSBjKCJpZDIiID0gImlkIikpDQoNCkZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX2Nsb3VkIDwtDQogIEZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX2Nsb3VkX3ByZTIgJT4lDQogIG5hbWVkX2dyb3VwX3NwbGl0KHBhMikNCg0KYGBgDQoNCiMjIyMgUnVuIE1vZGVsDQoNCmBgYHtyLCB3YXJuaW5nID0gZmFsc2V9DQpmaXRzX25vbl9zZWFyY2hfY2xvdWQgPC0gbW9kZWxfd3JhcHBlcl9mdW5jdGlvbihkZiA9IEZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX2Nsb3VkLHBvbHlfaW5kID0gMCkNCg0KYmVzdF9pbmRfbm9uX3NlYXJjaF9jbG91ZCA8LSANCiAgbGFwcGx5KDE6bGVuZ3RoKEZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX2Nsb3VkKSwgYmVzdF9pbmRfZnVuY3Rpb24sZGYgPSBmaXRzX25vbl9zZWFyY2hfY2xvdWQsDQogICAgICAgICBkZjIgPSBGaW5hbF9DTFNfMjAyMl9TdHVkeV9MaXN0X05vbl9TZWFyY2hfbW9kZWxfZmlsZV9jbG91ZCkgDQoNCmNvZWZfbm9uX3NlYXJjaF9jbG91ZCA8LSBiZXN0X2luZF9ub25fc2VhcmNoX2Nsb3VkICU+JSBiaW5kX3Jvd3MgI21ha2UgYSBtYXRyaXggb2YgYWxsIGNvZWZzDQoNCmJlc3RfZml0X25vbl9zZWFyY2hfY2xvdWQgPC0gYmVzdF9pbmRfbm9uX3NlYXJjaF9jbG91ZCAlPiUNCiAgc2V0X25hbWVzKG5hbWVzX2Z1bmN0aW9uKEZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX2Nsb3VkX3ByZSwgcGEyKSkgIA0KYGBgDQoNCiMjIyMgQ3JlYXRlIEdyYXBoIE9iamVjdA0KDQpgYGB7cn0NCmdyYXBoX2xpc3RfY2xvdWQgPC0gbGFwcGx5KDE6bGVuZ3RoKGJlc3RfZml0X25vbl9zZWFyY2hfY2xvdWQpLCBncmFwaGluZ19mdW5jdGlvbjQsIGRmMSA9IGJlc3RfZml0X25vbl9zZWFyY2hfY2xvdWQsIGRmMiA9IEZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX2Nsb3VkKQ0KYGBgDQoNCg0KYGBge3J9DQplbmRfdGltZSA8LSBTeXMudGltZSgpDQoNCnRpbWVfY2xvdWQgPSBlbmRfdGltZSAtIHN0YXJ0X3RpbWUNCmBgYA0KDQojIyMgWW91VHViZQ0KDQojIyMjIERhdGEgUmVhZGluDQoNCmBgYHtyfQ0KDQpzdGFydF90aW1lIDwtIFN5cy50aW1lKCkNCg0KRmluYWxfQ0xTXzIwMjJfU3R1ZHlfTGlzdF9Ob25fU2VhcmNoX21vZGVsX2ZpbGVfeW91dHViZV9wcmUgPC0NCiAgRmluYWxfQ0xTXzIwMjJfU3R1ZHlfTGlzdF9Ob25fU2VhcmNoX21vZGVsX2ZpbGUgJT4lDQogIGZpbHRlcihwYSAlaW4lIGMoIllvdVR1YmUgVFYiLCAiWVRNUCIpKSAlPiUNCiAgbXV0YXRlKA0KICAgIHBhID0gIllvdVR1YmUiLA0KICAgIHBhMiA9ICJZb3VUdWJlIg0KICApICU+JQ0KICAjICBmaWx0ZXIoYWJzb2x1dGVfbGlmdCA8IDUwMDApICU+JQ0KICBtdXRhdGUoDQogICAgaWQyID0gcm93X251bWJlcigpDQogICkNCg0KZGZfdGVzdCA8LQ0KICBGaW5hbF9DTFNfMjAyMl9TdHVkeV9MaXN0X05vbl9TZWFyY2hfbW9kZWxfZmlsZV95b3V0dWJlX3ByZSAlPiUNCiAgIyBzZWxlY3QoLXN0dWR5X2lkLCAtaWQyLCAtcmVnaW9uLCAtc2NhbGluZ19mYWN0b3IsIC1xdWFydGVyLCAtcGEsIC1zdHVkeV9uYW1lKQ0KICBzZWxlY3QoDQogICAgcmVnaW9uX3YyLCBjb3VudHJ5LCBjaGFubmVsLCB0YWN0aWMsDQogICAgIyB0cmVhdG1lbnRfdXNlcl9jb3VudDpjb250cm9sLA0KICAgIGNvc3Rfc3BlbnRfb25fZXhwb3NlZF9ncm91cDphYnNvbHV0ZV9saWZ0LCBwYXJzZWRfdHlwZQ0KICApDQoNCmlzb195dCA8LSBpc29sYXRpb25Gb3Jlc3QkbmV3KHNhbXBsZV9zaXplID0gbnJvdyhkZl90ZXN0KSwgbnVtX3RyZWVzID0gMTAwMDAsIHNlZWQgPSAxMTUzKQ0KDQppc29feXQkZml0KGRmX3Rlc3QpDQoNCnNjb3Jlc190cmFpbiA8LSBkZl90ZXN0ICU+JQ0KICBpc29feXQkcHJlZGljdCgpICU+JQ0KICBhcnJhbmdlKGRlc2MoYW5vbWFseV9zY29yZSkpDQoNCkZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX3lvdXR1YmVfcHJlMiA8LQ0KICBGaW5hbF9DTFNfMjAyMl9TdHVkeV9MaXN0X05vbl9TZWFyY2hfbW9kZWxfZmlsZV95b3V0dWJlX3ByZSAlPiUNCiAgbGVmdF9qb2luKHNjb3Jlc190cmFpbiwgYnkgPSBjKCJpZDIiID0gImlkIikpICU+JQ0KICBmaWx0ZXIoYXZlcmFnZV9kZXB0aCA+IDMuODkpDQoNCkZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX3lvdXR1YmUgPC0NCiAgRmluYWxfQ0xTXzIwMjJfU3R1ZHlfTGlzdF9Ob25fU2VhcmNoX21vZGVsX2ZpbGVfeW91dHViZV9wcmUyICU+JQ0KICBuYW1lZF9ncm91cF9zcGxpdChyZWdpb25fdjIpDQpgYGANCg0KIyMjIyBSdW4gTW9kZWwNCg0KYGBge3IsIHdhcm5pbmcgPSBmYWxzZX0NCmZpdHNfbm9uX3NlYXJjaF95b3V0dWJlIDwtIG1vZGVsX3dyYXBwZXJfZnVuY3Rpb24oZGYgPSBGaW5hbF9DTFNfMjAyMl9TdHVkeV9MaXN0X05vbl9TZWFyY2hfbW9kZWxfZmlsZV95b3V0dWJlLHBvbHlfaW5kID0gMCkNCg0KYmVzdF9pbmRfbm9uX3NlYXJjaF95b3V0dWJlIDwtIA0KICBsYXBwbHkoMTpsZW5ndGgoRmluYWxfQ0xTXzIwMjJfU3R1ZHlfTGlzdF9Ob25fU2VhcmNoX21vZGVsX2ZpbGVfeW91dHViZSksIGJlc3RfaW5kX2Z1bmN0aW9uLGRmID0gZml0c19ub25fc2VhcmNoX3lvdXR1YmUsDQogICAgICAgICBkZjIgPSBGaW5hbF9DTFNfMjAyMl9TdHVkeV9MaXN0X05vbl9TZWFyY2hfbW9kZWxfZmlsZV95b3V0dWJlKSANCg0KY29lZl9ub25fc2VhcmNoX3lvdXR1YmUgPC0gYmVzdF9pbmRfbm9uX3NlYXJjaF95b3V0dWJlICU+JSBiaW5kX3Jvd3MgI21ha2UgYSBtYXRyaXggb2YgYWxsIGNvZWZzDQoNCmJlc3RfZml0X25vbl9zZWFyY2hfeW91dHViZSA8LSBiZXN0X2luZF9ub25fc2VhcmNoX3lvdXR1YmUgJT4lDQogIHNldF9uYW1lcyhuYW1lc19mdW5jdGlvbihGaW5hbF9DTFNfMjAyMl9TdHVkeV9MaXN0X05vbl9TZWFyY2hfbW9kZWxfZmlsZV95b3V0dWJlX3ByZSwgcGEyKSkgIA0KYGBgDQoNCiMjIyMgQ3JlYXRlIEdyYXBoIE9iamVjdA0KDQpgYGB7cn0NCmdyYXBoX2xpc3RfeW91dHViZSA8LSBsYXBwbHkoMTpsZW5ndGgoYmVzdF9maXRfbm9uX3NlYXJjaF95b3V0dWJlKSwgZ3JhcGhpbmdfZnVuY3Rpb240LCBkZjEgPSBiZXN0X2ZpdF9ub25fc2VhcmNoX3lvdXR1YmUsIGRmMiA9IEZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX3lvdXR1YmUpDQpgYGANCg0KDQpgYGB7cn0NCmVuZF90aW1lIDwtIFN5cy50aW1lKCkNCg0KdGltZV95b3V0dWJlID0gZW5kX3RpbWUgLSBzdGFydF90aW1lDQpgYGANCg0KDQojIyMgRFNNDQoNCiMjIyMgRGF0YSBSZWFkaW4NCg0KYGBge3J9DQoNCnN0YXJ0X3RpbWUgPC0gU3lzLnRpbWUoKQ0KDQpGaW5hbF9DTFNfMjAyMl9TdHVkeV9MaXN0X05vbl9TZWFyY2hfbW9kZWxfZmlsZV9kc21fcHJlIDwtDQogIEZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlICU+JQ0KICBmaWx0ZXIocGEgPT0gIkRTTSIpICU+JQ0KICBmaWx0ZXIocmVnaW9uX3YyICE9ICJBUEFDIikgJT4lDQogICMgZmlsdGVyKGFic29sdXRlX2xpZnQgPCAxMDAwKSAjICU+JQ0KICAjIGZpbHRlcihzdHVkeV9pZCAhPSAnNjI5NzQyMCcpICMlPiUNCiAgIyAgZmlsdGVyKHN0dWR5X2lkICE9JzE0OTE2MTcxMScpICU+JQ0KICAjICBmaWx0ZXIoc3R1ZHlfaWQgIT0gJzE0ODYxMzAwMicpICU+JQ0KICAjIGZpbHRlcihzdHVkeV9pZCAhPSczMjg0NjI1JykgJT4lDQogICMgIGZpbHRlcihzdHVkeV9pZCAhPSczMzI5MTMxJykNCiAgbXV0YXRlKA0KICAgIGlkMiA9IHJvd19udW1iZXIoKQ0KICApDQoNCmRmX3Rlc3QgPC0NCiAgRmluYWxfQ0xTXzIwMjJfU3R1ZHlfTGlzdF9Ob25fU2VhcmNoX21vZGVsX2ZpbGVfZHNtX3ByZSAlPiUNCiAgIyBzZWxlY3QoLXN0dWR5X2lkLCAtaWQyLCAtcmVnaW9uLCAtc2NhbGluZ19mYWN0b3IsIC1xdWFydGVyLCAtcGEsIC1zdHVkeV9uYW1lKQ0KICBzZWxlY3QoDQogICAgcmVnaW9uX3YyLCBjb3VudHJ5LCBjaGFubmVsLCB0YWN0aWMsDQogICAgIyB0cmVhdG1lbnRfdXNlcl9jb3VudDpjb250cm9sLA0KICAgIGNvc3Rfc3BlbnRfb25fZXhwb3NlZF9ncm91cDphYnNvbHV0ZV9saWZ0DQogICkNCg0KaXNvX2RzbSA8LSBpc29sYXRpb25Gb3Jlc3QkbmV3KHNhbXBsZV9zaXplID0gbnJvdyhkZl90ZXN0KSwgbnVtX3RyZWVzID0gMTAwMDAsIHNlZWQgPSAxMTUyKQ0KDQppc29fZHNtJGZpdChkZl90ZXN0KQ0KDQpzY29yZXNfdHJhaW4gPC0gZGZfdGVzdCAlPiUNCiAgaXNvX2RzbSRwcmVkaWN0KCkgJT4lDQogIGFycmFuZ2UoZGVzYyhhbm9tYWx5X3Njb3JlKSkNCg0KRmluYWxfQ0xTXzIwMjJfU3R1ZHlfTGlzdF9Ob25fU2VhcmNoX21vZGVsX2ZpbGVfZHNtX3ByZTIgPC0NCiAgRmluYWxfQ0xTXzIwMjJfU3R1ZHlfTGlzdF9Ob25fU2VhcmNoX21vZGVsX2ZpbGVfZHNtX3ByZSAlPiUNCiAgbGVmdF9qb2luKHNjb3Jlc190cmFpbiwgYnkgPSBjKCJpZDIiID0gImlkIikpICU+JQ0KICBmaWx0ZXIoYXZlcmFnZV9kZXB0aCA+IDUpDQoNCkZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX2RzbSA8LQ0KICBGaW5hbF9DTFNfMjAyMl9TdHVkeV9MaXN0X05vbl9TZWFyY2hfbW9kZWxfZmlsZV9kc21fcHJlMiAlPiUNCiAgbmFtZWRfZ3JvdXBfc3BsaXQocmVnaW9uX3YyLCBjaGFubmVsKQ0KYGBgDQoNCiMjIyMgUnVuIE1vZGVsDQoNCmBgYHtyLCB3YXJuaW5nID0gZmFsc2V9DQpmaXRzX25vbl9zZWFyY2hfZHNtIDwtIG1vZGVsX3dyYXBwZXJfZnVuY3Rpb24oZGYgPSBGaW5hbF9DTFNfMjAyMl9TdHVkeV9MaXN0X05vbl9TZWFyY2hfbW9kZWxfZmlsZV9kc20scG9seV9pbmQgPSAwKQ0KDQpiZXN0X2luZF9ub25fc2VhcmNoX2RzbSA8LSANCiAgbGFwcGx5KDE6bGVuZ3RoKEZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX2RzbSksIGJlc3RfaW5kX2Z1bmN0aW9uLGRmID0gZml0c19ub25fc2VhcmNoX2RzbSwNCiAgICAgICAgIGRmMiA9IEZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX2RzbSkNCg0KY29lZl9ub25fc2VhcmNoX2RzbSA8LSBiZXN0X2luZF9ub25fc2VhcmNoX2RzbSAlPiUgYmluZF9yb3dzICNtYWtlIGEgbWF0cml4IG9mIGFsbCBjb2Vmcw0KDQpiZXN0X2ZpdF9ub25fc2VhcmNoX2RzbSA8LSBiZXN0X2luZF9ub25fc2VhcmNoX2RzbSAlPiUNCiAgc2V0X25hbWVzKG5hbWVzX2Z1bmN0aW9uKEZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX2RzbV9wcmUsIHJlZ2lvbl92MixjaGFubmVsKSkgIA0KYGBgDQoNCiMjIyMgQ3JlYXRlIEdyYXBoIE9iamVjdA0KDQpgYGB7cn0NCmdyYXBoX2xpc3RfZHNtIDwtIGxhcHBseSgxOmxlbmd0aChiZXN0X2ZpdF9ub25fc2VhcmNoX2RzbSksIGdyYXBoaW5nX2Z1bmN0aW9uNCwgZGYxID0gYmVzdF9maXRfbm9uX3NlYXJjaF9kc20sIGRmMiA9IEZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX2RzbSkNCmBgYA0KDQoNCmBgYHtyfQ0KZW5kX3RpbWUgPC0gU3lzLnRpbWUoKQ0KDQp0aW1lX2RzbSA9IGVuZF90aW1lIC0gc3RhcnRfdGltZQ0KYGBgDQoNCg0KIyMjIFBpeGVsDQoNCiMjIyMgRGF0YSBSZWFkaW4NCg0KYGBge3J9DQoNCnN0YXJ0X3RpbWUgPC0gU3lzLnRpbWUoKQ0KDQpGaW5hbF9DTFNfMjAyMl9TdHVkeV9MaXN0X05vbl9TZWFyY2hfbW9kZWxfZmlsZV9waXhlbF9wcmUgPC0NCiAgRmluYWxfQ0xTXzIwMjJfU3R1ZHlfTGlzdF9Ob25fU2VhcmNoX21vZGVsX2ZpbGUgJT4lDQogIGZpbHRlcihwYSA9PSAiUGl4ZWwiKSAlPiUNCiAgbXV0YXRlKA0KICAgIHBhMiA9ICJQaXhlbCAtIEFsbCBDaGFubmVsIg0KICApICU+JQ0KICAjICAgZmlsdGVyKGFic29sdXRlX2xpZnQgPCAxMDAwKSAgJT4lDQogICMgZmlsdGVyKHN0dWR5X2lkICE9ICc2Mjk3NDIwJykgIyU+JQ0KICAjICBmaWx0ZXIoc3R1ZHlfaWQgIT0nMTQ5MTYxNzExJykgJT4lDQogICMgIGZpbHRlcihzdHVkeV9pZCAhPSAnMTQ4NjEzMDAyJykgJT4lDQogICMgZmlsdGVyKHN0dWR5X2lkICE9JzMyODQ2MjUnKSAlPiUNCiAgIyAgZmlsdGVyKHN0dWR5X2lkICE9JzMzMjkxMzEnKQ0KICBtdXRhdGUoDQogICAgaWQyID0gcm93X251bWJlcigpDQogICkNCg0KZGZfdGVzdCA8LQ0KICBGaW5hbF9DTFNfMjAyMl9TdHVkeV9MaXN0X05vbl9TZWFyY2hfbW9kZWxfZmlsZV9waXhlbF9wcmUgJT4lDQogICMgc2VsZWN0KC1zdHVkeV9pZCwgLWlkMiwgLXJlZ2lvbiwgLXNjYWxpbmdfZmFjdG9yLCAtcXVhcnRlciwgLXBhLCAtc3R1ZHlfbmFtZSkNCiAgc2VsZWN0KA0KICAgIHJlZ2lvbl92MiwgY291bnRyeSwgY2hhbm5lbCwgdGFjdGljLA0KICAgICMgdHJlYXRtZW50X3VzZXJfY291bnQ6Y29udHJvbCwNCiAgICBjb3N0X3NwZW50X29uX2V4cG9zZWRfZ3JvdXA6YWJzb2x1dGVfbGlmdA0KICApDQoNCmlzb19waXhlbCA8LSBpc29sYXRpb25Gb3Jlc3QkbmV3KHNhbXBsZV9zaXplID0gbnJvdyhkZl90ZXN0KSwgbnVtX3RyZWVzID0gMTAwMDAsIHNlZWQgPSAxMTUyKQ0KDQppc29fcGl4ZWwkZml0KGRmX3Rlc3QpDQoNCnNjb3Jlc190cmFpbiA8LSBkZl90ZXN0ICU+JQ0KICBpc29fcGl4ZWwkcHJlZGljdCgpICU+JQ0KICBhcnJhbmdlKGRlc2MoYW5vbWFseV9zY29yZSkpDQoNCkZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX3BpeGVsX3ByZTIgPC0NCiAgRmluYWxfQ0xTXzIwMjJfU3R1ZHlfTGlzdF9Ob25fU2VhcmNoX21vZGVsX2ZpbGVfcGl4ZWxfcHJlICU+JQ0KICBsZWZ0X2pvaW4oc2NvcmVzX3RyYWluLCBieSA9IGMoImlkMiIgPSAiaWQiKSkgJT4lDQogIGZpbHRlcihhdmVyYWdlX2RlcHRoID4gMy4xKQ0KDQpGaW5hbF9DTFNfMjAyMl9TdHVkeV9MaXN0X05vbl9TZWFyY2hfbW9kZWxfZmlsZV9waXhlbF9wcmUyDQoNCg0KRmluYWxfQ0xTXzIwMjJfU3R1ZHlfTGlzdF9Ob25fU2VhcmNoX21vZGVsX2ZpbGVfcGl4ZWwgPC0NCiAgRmluYWxfQ0xTXzIwMjJfU3R1ZHlfTGlzdF9Ob25fU2VhcmNoX21vZGVsX2ZpbGVfcGl4ZWxfcHJlMiAlPiUNCiAgbmFtZWRfZ3JvdXBfc3BsaXQocGEyKQ0KYGBgDQoNCiMjIyMgUnVuIE1vZGVsDQoNCmBgYHtyLCB3YXJuaW5nID0gZmFsc2V9DQpmaXRzX25vbl9zZWFyY2hfcGl4ZWwgPC0gbW9kZWxfd3JhcHBlcl9mdW5jdGlvbihkZiA9IEZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX3BpeGVsLHBvbHlfaW5kID0gMCkNCg0KYmVzdF9pbmRfbm9uX3NlYXJjaF9waXhlbCA8LSANCiAgbGFwcGx5KDE6bGVuZ3RoKEZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX3BpeGVsKSwgYmVzdF9pbmRfZnVuY3Rpb24sZGYgPSBmaXRzX25vbl9zZWFyY2hfcGl4ZWwsDQogICAgICAgICBkZjIgPSBGaW5hbF9DTFNfMjAyMl9TdHVkeV9MaXN0X05vbl9TZWFyY2hfbW9kZWxfZmlsZV9waXhlbCkgDQoNCmNvZWZfbm9uX3NlYXJjaF9waXhlbCA8LSBiZXN0X2luZF9ub25fc2VhcmNoX3BpeGVsICU+JSBiaW5kX3Jvd3MgI21ha2UgYSBtYXRyaXggb2YgYWxsIGNvZWZzDQoNCmJlc3RfZml0X25vbl9zZWFyY2hfcGl4ZWwgPC0gYmVzdF9pbmRfbm9uX3NlYXJjaF9waXhlbCAlPiUNCiAgc2V0X25hbWVzKG5hbWVzX2Z1bmN0aW9uKEZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX3BpeGVsX3ByZSwgcGEyKSkgIA0KYGBgDQoNCiMjIyMgQ3JlYXRlIEdyYXBoIE9iamVjdA0KDQpgYGB7cn0NCmdyYXBoX2xpc3RfcGl4ZWwgPC0gbGFwcGx5KDE6bGVuZ3RoKGJlc3RfZml0X25vbl9zZWFyY2hfcGl4ZWwpLCBncmFwaGluZ19mdW5jdGlvbjQsIGRmMSA9IGJlc3RfZml0X25vbl9zZWFyY2hfcGl4ZWwsIGRmMiA9IEZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX3BpeGVsKQ0KYGBgDQoNCg0KYGBge3J9DQplbmRfdGltZSA8LSBTeXMudGltZSgpDQoNCnRpbWVfcGl4ZWwgPSBlbmRfdGltZSAtIHN0YXJ0X3RpbWUNCmBgYA0KDQoNCiMjIyBGaQ0KDQojIyMjIERhdGEgUmVhZGluDQoNCmBgYHtyfQ0KDQpzdGFydF90aW1lIDwtIFN5cy50aW1lKCkNCg0KRmluYWxfQ0xTXzIwMjJfU3R1ZHlfTGlzdF9Ob25fU2VhcmNoX21vZGVsX2ZpbGVfZmlfcHJlIDwtDQogIEZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlICU+JQ0KICBmaWx0ZXIocGEgPT0gIkdvb2dsZSBGaSIpICU+JQ0KICBtdXRhdGUoDQogICAgcGEyID0gIkZpIC0gQWxsIENoYW5uZWwiDQogICkgJT4lDQogICMgICBmaWx0ZXIoYWJzb2x1dGVfbGlmdCA8IDEwMDApICAlPiUNCiAgIyBmaWx0ZXIoc3R1ZHlfaWQgIT0gJzYyOTc0MjAnKSAjJT4lDQogICMgIGZpbHRlcihzdHVkeV9pZCAhPScxNDkxNjE3MTEnKSAlPiUNCiAgIyAgZmlsdGVyKHN0dWR5X2lkICE9ICcxNDg2MTMwMDInKSAlPiUNCiAgIyBmaWx0ZXIoc3R1ZHlfaWQgIT0nMzI4NDYyNScpICU+JQ0KICAjICBmaWx0ZXIoc3R1ZHlfaWQgIT0nMzMyOTEzMScpDQogIG11dGF0ZSgNCiAgICBpZDIgPSByb3dfbnVtYmVyKCkNCiAgKQ0KDQpkZl90ZXN0IDwtDQogIEZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX2ZpX3ByZSAlPiUNCiAgIyBzZWxlY3QoLXN0dWR5X2lkLCAtaWQyLCAtcmVnaW9uLCAtc2NhbGluZ19mYWN0b3IsIC1xdWFydGVyLCAtcGEsIC1zdHVkeV9uYW1lKQ0KICBzZWxlY3QoDQogICAgcmVnaW9uX3YyLCBjb3VudHJ5LCBjaGFubmVsLCB0YWN0aWMsDQogICAgIyB0cmVhdG1lbnRfdXNlcl9jb3VudDpjb250cm9sLA0KICAgIGNvc3Rfc3BlbnRfb25fZXhwb3NlZF9ncm91cDphYnNvbHV0ZV9saWZ0DQogICkNCg0KaXNvX2ZpIDwtIGlzb2xhdGlvbkZvcmVzdCRuZXcoc2FtcGxlX3NpemUgPSBucm93KGRmX3Rlc3QpLCBudW1fdHJlZXMgPSAxMDAwMCwgc2VlZCA9IDExNTIpDQoNCmlzb19maSRmaXQoZGZfdGVzdCkNCg0Kc2NvcmVzX3RyYWluIDwtIGRmX3Rlc3QgJT4lDQogIGlzb19maSRwcmVkaWN0KCkgJT4lDQogIGFycmFuZ2UoZGVzYyhhbm9tYWx5X3Njb3JlKSkNCg0KRmluYWxfQ0xTXzIwMjJfU3R1ZHlfTGlzdF9Ob25fU2VhcmNoX21vZGVsX2ZpbGVfZmlfcHJlMiA8LQ0KICBGaW5hbF9DTFNfMjAyMl9TdHVkeV9MaXN0X05vbl9TZWFyY2hfbW9kZWxfZmlsZV9maV9wcmUgJT4lDQogIGxlZnRfam9pbihzY29yZXNfdHJhaW4sIGJ5ID0gYygiaWQyIiA9ICJpZCIpKSAlPiUNCiAgZmlsdGVyKGF2ZXJhZ2VfZGVwdGggPiA0Ljc1KQ0KDQpGaW5hbF9DTFNfMjAyMl9TdHVkeV9MaXN0X05vbl9TZWFyY2hfbW9kZWxfZmlsZV9maV9wcmUyDQoNCg0KRmluYWxfQ0xTXzIwMjJfU3R1ZHlfTGlzdF9Ob25fU2VhcmNoX21vZGVsX2ZpbGVfZmkgPC0NCiAgRmluYWxfQ0xTXzIwMjJfU3R1ZHlfTGlzdF9Ob25fU2VhcmNoX21vZGVsX2ZpbGVfZmlfcHJlMiAlPiUNCiAgbmFtZWRfZ3JvdXBfc3BsaXQoY2hhbm5lbCkNCmBgYA0KDQojIyMjIFJ1biBNb2RlbA0KDQpgYGB7ciwgd2FybmluZyA9IGZhbHNlfQ0KZml0c19ub25fc2VhcmNoX2ZpIDwtIG1vZGVsX3dyYXBwZXJfZnVuY3Rpb24oZGYgPSBGaW5hbF9DTFNfMjAyMl9TdHVkeV9MaXN0X05vbl9TZWFyY2hfbW9kZWxfZmlsZV9maSxwb2x5X2luZCA9IDApDQoNCmJlc3RfaW5kX25vbl9zZWFyY2hfZmkgPC0gDQogIGxhcHBseSgxOmxlbmd0aChGaW5hbF9DTFNfMjAyMl9TdHVkeV9MaXN0X05vbl9TZWFyY2hfbW9kZWxfZmlsZV9maSksIGJlc3RfaW5kX2Z1bmN0aW9uLGRmID0gZml0c19ub25fc2VhcmNoX2ZpLA0KICAgICAgICAgZGYyID0gRmluYWxfQ0xTXzIwMjJfU3R1ZHlfTGlzdF9Ob25fU2VhcmNoX21vZGVsX2ZpbGVfZmkpIA0KDQpjb2VmX25vbl9zZWFyY2hfZmkgPC0gYmVzdF9pbmRfbm9uX3NlYXJjaF9maSAlPiUgYmluZF9yb3dzICNtYWtlIGEgbWF0cml4IG9mIGFsbCBjb2Vmcw0KDQpiZXN0X2ZpdF9ub25fc2VhcmNoX2ZpIDwtIGJlc3RfaW5kX25vbl9zZWFyY2hfZmkgJT4lDQogIHNldF9uYW1lcyhuYW1lc19mdW5jdGlvbihGaW5hbF9DTFNfMjAyMl9TdHVkeV9MaXN0X05vbl9TZWFyY2hfbW9kZWxfZmlsZV9maV9wcmUsIHBhMikpICANCmBgYA0KDQojIyMjIENyZWF0ZSBHcmFwaCBPYmplY3QNCg0KYGBge3J9DQpncmFwaF9saXN0X2ZpIDwtIGxhcHBseSgxOmxlbmd0aChiZXN0X2ZpdF9ub25fc2VhcmNoX2ZpKSwgZ3JhcGhpbmdfZnVuY3Rpb240LCBkZjEgPSBiZXN0X2ZpdF9ub25fc2VhcmNoX2ZpLCBkZjIgPSBGaW5hbF9DTFNfMjAyMl9TdHVkeV9MaXN0X05vbl9TZWFyY2hfbW9kZWxfZmlsZV9maSkNCmBgYA0KDQoNCmBgYHtyfQ0KZW5kX3RpbWUgPC0gU3lzLnRpbWUoKQ0KDQp0aW1lX2ZpID0gZW5kX3RpbWUgLSBzdGFydF90aW1lDQpgYGANCg0KDQojIyMgU01CIC0gUUxlYWRzDQoNCiMjIyMgRGF0YSBSZWFkaW4NCg0KYGBge3J9DQoNCnN0YXJ0X3RpbWUgPC0gU3lzLnRpbWUoKQ0KDQpGaW5hbF9DTFNfMjAyMl9TdHVkeV9MaXN0X05vbl9TZWFyY2hfbW9kZWxfZmlsZV9zbWJxX3ByZSA8LQ0KICBGaW5hbF9DTFNfMjAyMl9TdHVkeV9MaXN0X05vbl9TZWFyY2hfbW9kZWxfZmlsZSAlPiUNCiAgZmlsdGVyKGdyb3VwZWRfY29udmVyc2lvbiA9PSAnTGVuYSBRIExlYWQnKSAlPiUNCiAgbXV0YXRlKA0KICAgIHBhMiA9ICJTTUIgLSBRLUxlYWQiDQogICkgJT4lDQogICMgICBmaWx0ZXIoYWJzb2x1dGVfbGlmdCA8IDEwMDApICAlPiUNCiAgIyBmaWx0ZXIoc3R1ZHlfaWQgIT0gJzYyOTc0MjAnKSAjJT4lDQogICMgIGZpbHRlcihzdHVkeV9pZCAhPScxNDkxNjE3MTEnKSAlPiUNCiAgIyAgZmlsdGVyKHN0dWR5X2lkICE9ICcxNDg2MTMwMDInKSAlPiUNCiAgIyBmaWx0ZXIoc3R1ZHlfaWQgIT0nMzI4NDYyNScpICU+JQ0KICAjICBmaWx0ZXIoc3R1ZHlfaWQgIT0nMzMyOTEzMScpDQogIG11dGF0ZSgNCiAgICBpZDIgPSByb3dfbnVtYmVyKCkNCiAgKQ0KDQpkZl90ZXN0IDwtDQogIEZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX3NtYnFfcHJlICU+JQ0KICAjIHNlbGVjdCgtc3R1ZHlfaWQsIC1pZDIsIC1yZWdpb24sIC1zY2FsaW5nX2ZhY3RvciwgLXF1YXJ0ZXIsIC1wYSwgLXN0dWR5X25hbWUpDQogIHNlbGVjdCgNCiAgICByZWdpb25fdjIsIGNvdW50cnksIGNoYW5uZWwsIHRhY3RpYywNCiAgICAjIHRyZWF0bWVudF91c2VyX2NvdW50OmNvbnRyb2wsDQogICAgY29zdF9zcGVudF9vbl9leHBvc2VkX2dyb3VwOmFic29sdXRlX2xpZnQNCiAgKQ0KDQppc29fc21icSA8LSBpc29sYXRpb25Gb3Jlc3QkbmV3KHNhbXBsZV9zaXplID0gbnJvdyhkZl90ZXN0KSwgbnVtX3RyZWVzID0gMTAwMDAsIHNlZWQgPSAxMTUyKQ0KDQppc29fc21icSRmaXQoZGZfdGVzdCkNCg0Kc2NvcmVzX3RyYWluIDwtIGRmX3Rlc3QgJT4lDQogIGlzb19zbWJxJHByZWRpY3QoKSAlPiUNCiAgYXJyYW5nZShkZXNjKGFub21hbHlfc2NvcmUpKQ0KDQpGaW5hbF9DTFNfMjAyMl9TdHVkeV9MaXN0X05vbl9TZWFyY2hfbW9kZWxfZmlsZV9zbWJxX3ByZTIgPC0NCiAgRmluYWxfQ0xTXzIwMjJfU3R1ZHlfTGlzdF9Ob25fU2VhcmNoX21vZGVsX2ZpbGVfc21icV9wcmUgJT4lDQogIGxlZnRfam9pbihzY29yZXNfdHJhaW4sIGJ5ID0gYygiaWQyIiA9ICJpZCIpKSAlPiUgDQogIGZpbHRlcihhdmVyYWdlX2RlcHRoID4gMSkNCg0KRmluYWxfQ0xTXzIwMjJfU3R1ZHlfTGlzdF9Ob25fU2VhcmNoX21vZGVsX2ZpbGVfc21icSA8LQ0KICBGaW5hbF9DTFNfMjAyMl9TdHVkeV9MaXN0X05vbl9TZWFyY2hfbW9kZWxfZmlsZV9zbWJxX3ByZTIgJT4lDQogIG5hbWVkX2dyb3VwX3NwbGl0KHBhMikNCmBgYA0KDQojIyMjIFJ1biBNb2RlbA0KDQpgYGB7ciwgd2FybmluZyA9IGZhbHNlfQ0KZml0c19ub25fc2VhcmNoX3NtYnEgPC0gbW9kZWxfd3JhcHBlcl9mdW5jdGlvbihkZiA9IEZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX3NtYnEscG9seV9pbmQgPSAwKQ0KDQpiZXN0X2luZF9ub25fc2VhcmNoX3NtYnEgPC0gDQogIGxhcHBseSgxOmxlbmd0aChGaW5hbF9DTFNfMjAyMl9TdHVkeV9MaXN0X05vbl9TZWFyY2hfbW9kZWxfZmlsZV9zbWJxKSwgYmVzdF9pbmRfZnVuY3Rpb24sZGYgPSBmaXRzX25vbl9zZWFyY2hfc21icSwNCiAgICAgICAgIGRmMiA9IEZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX3NtYnEpIA0KDQpjb2VmX25vbl9zZWFyY2hfc21icSA8LSBiZXN0X2luZF9ub25fc2VhcmNoX3NtYnEgJT4lIGJpbmRfcm93cyAjbWFrZSBhIG1hdHJpeCBvZiBhbGwgY29lZnMNCg0KYmVzdF9maXRfbm9uX3NlYXJjaF9zbWJxIDwtIGJlc3RfaW5kX25vbl9zZWFyY2hfc21icSAlPiUNCiAgc2V0X25hbWVzKG5hbWVzX2Z1bmN0aW9uKEZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX3NtYnFfcHJlLCBwYTIpKSAgDQpgYGANCg0KIyMjIyBDcmVhdGUgR3JhcGggT2JqZWN0DQoNCmBgYHtyfQ0KZ3JhcGhfbGlzdF9zbWJxIDwtIGxhcHBseSgxOmxlbmd0aChiZXN0X2ZpdF9ub25fc2VhcmNoX3NtYnEpLCBncmFwaGluZ19mdW5jdGlvbjQsIGRmMSA9IGJlc3RfZml0X25vbl9zZWFyY2hfc21icSwgZGYyID0gRmluYWxfQ0xTXzIwMjJfU3R1ZHlfTGlzdF9Ob25fU2VhcmNoX21vZGVsX2ZpbGVfc21icSkNCmBgYA0KDQoNCmBgYHtyfQ0KZW5kX3RpbWUgPC0gU3lzLnRpbWUoKQ0KDQp0aW1lX3NtYnEgPSBlbmRfdGltZSAtIHN0YXJ0X3RpbWUNCmBgYA0KDQoNCiMjIyBTTUIgLSBCTGVhZHMNCg0KIyMjIyBEYXRhIFJlYWRpbg0KDQpgYGB7cn0NCg0Kc3RhcnRfdGltZSA8LSBTeXMudGltZSgpDQoNCkZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX3NtYmJfcHJlIDwtDQogIEZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlICU+JQ0KICBmaWx0ZXIocGEgPT0gIlNNQiIgJiBncm91cGVkX2NvbnZlcnNpb24gPT0gJ0xlbmEgQiBMZWFkJykgJT4lDQogIG11dGF0ZSgNCiAgICBwYTIgPSAiU01CIC0gQi1MZWFkIg0KICApICU+JQ0KICAjICAgZmlsdGVyKGFic29sdXRlX2xpZnQgPCAxMDAwKSAgJT4lDQogICMgZmlsdGVyKHN0dWR5X2lkICE9ICc2Mjk3NDIwJykgIyU+JQ0KICAjICBmaWx0ZXIoc3R1ZHlfaWQgIT0nMTQ5MTYxNzExJykgJT4lDQogICMgIGZpbHRlcihzdHVkeV9pZCAhPSAnMTQ4NjEzMDAyJykgJT4lDQogICMgZmlsdGVyKHN0dWR5X2lkICE9JzMyODQ2MjUnKSAlPiUNCiAgIyAgZmlsdGVyKHN0dWR5X2lkICE9JzMzMjkxMzEnKQ0KICBtdXRhdGUoDQogICAgaWQyID0gcm93X251bWJlcigpDQogICkNCg0KZGZfdGVzdCA8LQ0KICBGaW5hbF9DTFNfMjAyMl9TdHVkeV9MaXN0X05vbl9TZWFyY2hfbW9kZWxfZmlsZV9zbWJiX3ByZSAlPiUNCiAgIyBzZWxlY3QoLXN0dWR5X2lkLCAtaWQyLCAtcmVnaW9uLCAtc2NhbGluZ19mYWN0b3IsIC1xdWFydGVyLCAtcGEsIC1zdHVkeV9uYW1lKQ0KICBzZWxlY3QoDQogICAgcmVnaW9uX3YyLCBjb3VudHJ5LCBjaGFubmVsLCB0YWN0aWMsDQogICAgIyB0cmVhdG1lbnRfdXNlcl9jb3VudDpjb250cm9sLA0KICAgIGNvc3Rfc3BlbnRfb25fZXhwb3NlZF9ncm91cDphYnNvbHV0ZV9saWZ0DQogICkNCg0KaXNvX3NtYmIgPC0gaXNvbGF0aW9uRm9yZXN0JG5ldyhzYW1wbGVfc2l6ZSA9IG5yb3coZGZfdGVzdCksIG51bV90cmVlcyA9IDEwMDAwLCBzZWVkID0gMTE1MikNCg0KaXNvX3NtYmIkZml0KGRmX3Rlc3QpDQoNCnNjb3Jlc190cmFpbiA8LSBkZl90ZXN0ICU+JQ0KICBpc29fc21iYiRwcmVkaWN0KCkgJT4lDQogIGFycmFuZ2UoZGVzYyhhbm9tYWx5X3Njb3JlKSkNCg0KRmluYWxfQ0xTXzIwMjJfU3R1ZHlfTGlzdF9Ob25fU2VhcmNoX21vZGVsX2ZpbGVfc21iYl9wcmUyIDwtDQogIEZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX3NtYmJfcHJlICU+JQ0KICBsZWZ0X2pvaW4oc2NvcmVzX3RyYWluLCBieSA9IGMoImlkMiIgPSAiaWQiKSkgJT4lIA0KICBmaWx0ZXIoYXZlcmFnZV9kZXB0aCA+IDQpDQoNCkZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX3NtYmIgPC0NCiAgRmluYWxfQ0xTXzIwMjJfU3R1ZHlfTGlzdF9Ob25fU2VhcmNoX21vZGVsX2ZpbGVfc21iYl9wcmUyICU+JQ0KICBuYW1lZF9ncm91cF9zcGxpdChjaGFubmVsKQ0KYGBgDQoNCiMjIyMgUnVuIE1vZGVsDQoNCmBgYHtyLCB3YXJuaW5nID0gZmFsc2V9DQpmaXRzX25vbl9zZWFyY2hfc21iYiA8LSBtb2RlbF93cmFwcGVyX2Z1bmN0aW9uKGRmID0gRmluYWxfQ0xTXzIwMjJfU3R1ZHlfTGlzdF9Ob25fU2VhcmNoX21vZGVsX2ZpbGVfc21iYixwb2x5X2luZCA9IDApDQoNCmJlc3RfaW5kX25vbl9zZWFyY2hfc21iYiA8LSANCiAgbGFwcGx5KDE6bGVuZ3RoKEZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX3NtYmIpLCBiZXN0X2luZF9mdW5jdGlvbixkZiA9IGZpdHNfbm9uX3NlYXJjaF9zbWJiLA0KICAgICAgICAgZGYyID0gRmluYWxfQ0xTXzIwMjJfU3R1ZHlfTGlzdF9Ob25fU2VhcmNoX21vZGVsX2ZpbGVfc21iYikgDQoNCmNvZWZfbm9uX3NlYXJjaF9zbWJiIDwtIGJlc3RfaW5kX25vbl9zZWFyY2hfc21iYiAlPiUgYmluZF9yb3dzICNtYWtlIGEgbWF0cml4IG9mIGFsbCBjb2Vmcw0KDQpiZXN0X2ZpdF9ub25fc2VhcmNoX3NtYmIgPC0gYmVzdF9pbmRfbm9uX3NlYXJjaF9zbWJiICU+JQ0KICBzZXRfbmFtZXMobmFtZXNfZnVuY3Rpb24oRmluYWxfQ0xTXzIwMjJfU3R1ZHlfTGlzdF9Ob25fU2VhcmNoX21vZGVsX2ZpbGVfc21iYl9wcmUsIGNoYW5uZWwpKSAgDQpgYGANCg0KIyMjIyBDcmVhdGUgR3JhcGggT2JqZWN0DQoNCmBgYHtyfQ0KZ3JhcGhfbGlzdF9zbWJiIDwtIGxhcHBseSgxOmxlbmd0aChiZXN0X2ZpdF9ub25fc2VhcmNoX3NtYmIpLCBncmFwaGluZ19mdW5jdGlvbjQsIGRmMSA9IGJlc3RfZml0X25vbl9zZWFyY2hfc21iYiwgZGYyID0gRmluYWxfQ0xTXzIwMjJfU3R1ZHlfTGlzdF9Ob25fU2VhcmNoX21vZGVsX2ZpbGVfc21iYikNCmBgYA0KDQoNCmBgYHtyfQ0KZW5kX3RpbWUgPC0gU3lzLnRpbWUoKQ0KDQp0aW1lX3NtYmIgPSBlbmRfdGltZSAtIHN0YXJ0X3RpbWUNCmBgYA0KDQojIyBFeHBvcnQgYWxsIGdyYXBoIGxpc3RzDQoNCmBgYHtyfQ0KZ3JhcGhfbmFtZXMgPC0gbWdldChscyhwYXQgPSAnZ3JhcGhfbGlzdF8nKSkNCiAgIA0KZGZfbmFtZXMgPC0gbWdldChzZXRkaWZmKGxzKHBhdHRlcm4gPSAnRmluYWxfQ0xTXzIwMjJfU3R1ZHlfTGlzdF9Ob25fU2VhcmNoX21vZGVsX2ZpbGVfJyksIGxzKHBhdHRlcm4gPSAicHJlIikpKQ0KDQojcm0oRmluYWxfQ0xTXzIwMjJfU3R1ZHlfTGlzdF9Ob25fU2VhcmNoX21vZGVsX2ZpbGVfQ2hyb21lLEZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX0Nsb3VkLEZpbmFsX0NMU18yMDIyX1N0dWR5X0xpc3RfTm9uX1NlYXJjaF9tb2RlbF9maWxlX1lvdVR1YmUpDQoNCiNsYXBwbHkoMTpsZW5ndGgoZ3JhcGhfbmFtZXMpLA0KIyAgICAgIGZ1bmN0aW9uKGopIHsNCiNsYXBwbHkoMTpsZW5ndGgoZGZfbmFtZXNbW2pdXSksZXhwb3J0X3JwbG90c19mdW5jdGlvbjIsc3RhcnRpbmdfbmFtZSA9ICJOb25fU2VhcmNoXyIsZm9sZGVyX25hbWUgPSBmb2xkZXJfbmFtZSxkZl9saXN0ID0gI2RmX25hbWVzW1tqXV0sZ3JhcGhpbmdfbGlzdCA9IGdyYXBoX25hbWVzW2pdW1sxXV0pDQojICAgICAgfQ0KIyAgICAgICApDQpgYGANCg0KIyMgR3JpZCBvZiBhbGwgUmVzcG9uc2UgQ3VydmVzDQoNClsqU3ViIFBsb3QgRG9jdW1lbnRhdGlvbipdKGh0dHBzOi8vcGxvdGx5LmNvbS9yL3N1YnBsb3RzLykNCg0KYGBge3IsIGZpZy5oZWlnaHQ9IDE1LCBlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmcgPSBGQUxTRX0NCg0KbGFwcGx5KDE6bGVuZ3RoKGdyYXBoX25hbWVzKSwNCmZ1bmN0aW9uKGkpew0KICBzdWJwbG90KGdyYXBoX25hbWVzW2ldW1sxXV0sIG5yb3dzID0gbGVuZ3RoKGdyYXBoX25hbWVzW2ldW1sxXV0pKQ0KfQ0KKQ0KDQoNCmxhcHBseSgxOmxlbmd0aChncmFwaF9uYW1lcyksDQpmdW5jdGlvbihpKXsNCiNwMSA9IGdyYXBoX25hbWVzW2ldW1sxXV0NCmRvLmNhbGwoZ3JpZC5hcnJhbmdlLGdyYXBoX25hbWVzW2ldW1sxXV0pDQojcmV0dXJuKGdyaWQuYXJyYW5nZShncm9icyA9IHAxKSkNCn0NCikNCg0KYGBgDQoNCiMjIENvZWYgTWF0cml4DQoNCmBgYHtyfQ0KY29lZi4yX21hdHJpeCA8LSBtZ2V0KChscyhwYXQgPSAnY29lZl8nKSkpICU+JSAgYmluZF9yb3dzKCkNCg0KY29lZi4yX21hdHJpeA0KDQoNCmBgYA0KDQojIyBHcmFwaHMgd2l0aCBBbm9tYWx5IFNjb3Jlcw0KDQpgYGB7cn0NCmdyYXBoX2xpc3QuZmkgPC0gbGFwcGx5KDE6bGVuZ3RoKGJlc3RfZml0X25vbl9zZWFyY2hfZmkpLCBncmFwaGluZ19mdW5jdGlvbjRfd19hbm9tLCBkZjEgPSBiZXN0X2ZpdF9ub25fc2VhcmNoX2ZpLCBkZjIgPSBGaW5hbF9DTFNfMjAyMl9TdHVkeV9MaXN0X05vbl9TZWFyY2hfbW9kZWxfZmlsZV9maSkNCg0KIyMjIEFkZCBHRyBUZXh0IFJlcGVsDQpnZ3Bsb3RseShncmFwaF9saXN0LmZpW1szXV0pDQoNCmBgYA0KDQojIENyZWF0ZSBhbGwgUmVzcG9uc2UgQ3VydmVzIC0gUmlkZ2UvTGFzc28NCg0KYGBge3IsIHdhcm5pbmcgPSBGQUxTRX0NCg0Kc3RhcnRfdGltZSA8LSBTeXMudGltZSgpDQoNCmZpdHMubm9uLnNlYXJjaC5SSURHRV9MQVNTTyA8LSBsYXBwbHkoDQogIDE6bGVuZ3RoKGRmX25hbWVzKSwNCiAgZnVuY3Rpb24oaSkgew0KICAgIG1vZGVsX3dyYXBwZXJfZnVuY3Rpb24oZGYgPSBkZl9uYW1lc1tpXVtbMV1dLHBvbHlfaW5kID0gMCkNCiAgfQ0KKQ0KDQplbmRfdGltZSA8LSBTeXMudGltZSgpDQoNCmNvbWJpbmVkX3JpZGdlX3RpbWUgPC0gc3RhcnRfdGltZSAtIGVuZF90aW1lDQoNCmJlc3QuaW5kLm5vbi5zZWFyY2guUklER0VfTEFTU08gPC0gbGFwcGx5KA0KICAxOmxlbmd0aChkZl9uYW1lcyksDQogIGZ1bmN0aW9uKGkpIHsgICANCiAgbGFwcGx5KDE6bGVuZ3RoKGRmX25hbWVzW2ldW1sxXV0pLCBiZXN0X2luZF9mdW5jdGlvbixkZiA9IGZpdHMubm9uLnNlYXJjaC5SSURHRV9MQVNTT1tpXVtbMV1dLA0KICAgICAgICAgZGYyID0gZGZfbmFtZXNbaV1bWzFdXSkNCiAgfQ0KKQ0KDQpjb2VmLm5vbi5zZWFyY2guUklER0VfTEFTU08gPC0gbGFwcGx5KA0KICAxOmxlbmd0aChkZl9uYW1lcyksDQogIGZ1bmN0aW9uIChpKXsNCiAgYmVzdC5pbmQubm9uLnNlYXJjaC5SSURHRV9MQVNTT1tpXVtbMV1dICU+JSBiaW5kX3Jvd3MNCiAgfQ0KKSAlPiUNCiAgYmluZF9yb3dzKCkgJT4lIA0KICBhcy5kYXRhLmZyYW1lKCkgJT4lIA0KIyAgbXV0YXRlKA0KIyAgICBjb3N0X3AyID0gMCwNCiMgICAgbGFtYmRhID0gMCwNCiMgICAgYWxwaGEgPSAwLA0KIyAgICBwb3dlcnMyID0gMA0KIyAgKSAlPiUgDQogIHNlbGVjdChvbmVfb2YoY29sbmFtZXMoY29lZi4yX21hdHJpeCkpKQ0KDQoNCmJlc3QuZml0Lm5vbi5zZWFyY2guUklER0VfTEFTU08gPC0gbGFwcGx5KDE6bGVuZ3RoKGRmX25hbWVzKSwNCiAgICAgIGZ1bmN0aW9uKGopIHsNCmxhcHBseSgxOmxlbmd0aChiZXN0LmluZC5ub24uc2VhcmNoLlJJREdFX0xBU1NPW1tqXV0pLA0KICAgICAgZnVuY3Rpb24oaSl7DQogICAgICAgIGJlc3QuaW5kLm5vbi5zZWFyY2guUklER0VfTEFTU09bal1bWzFdXVtpXSAlPiUgDQogICAgICAgIHNldF9uYW1lcyhubSA9IGJlc3QuaW5kLm5vbi5zZWFyY2guUklER0VfTEFTU09bal1bWzFdXVtbaV1dWyJtb2RlbCJdKQ0KICAgICAgfSANCikNCiAgICAgIH0NCiAgICAgICApDQogIA0KDQoNCmBgYA0KDQoNCiMgQ3JlYXRlIGFsbCBSZXNwb25zZSBDdXJ2ZXMgLSBSTE0NCg0KYGBge3IsIHdhcm5pbmcgPSBGQUxTRX0NCg0KDQpzdGFydF90aW1lIDwtIFN5cy50aW1lKCkNCg0KZml0cy5ub24uc2VhcmNoLlJMTSA8LSBsYXBwbHkoDQogIDE6bGVuZ3RoKGRmX25hbWVzKSwNCiAgZnVuY3Rpb24oaSkgew0KICAgIG1vZGVsX3dyYXBwZXJfZnVuY3Rpb24yKGRmID0gZGZfbmFtZXNbaV1bWzFdXSkNCiAgfQ0KKQ0KDQplbmRfdGltZSA8LSBTeXMudGltZSgpDQoNCmNvbWJpbmVkX3JsbV90aW1lIDwtIHN0YXJ0X3RpbWUgLSBlbmRfdGltZQ0KDQpiZXN0LmluZC5ub24uc2VhcmNoLlJMTSA8LSBsYXBwbHkoDQogIDE6bGVuZ3RoKGRmX25hbWVzKSwNCiAgZnVuY3Rpb24oaSkgeyAgIA0KICBsYXBwbHkoMTpsZW5ndGgoZGZfbmFtZXNbaV1bWzFdXSksIGJlc3RfaW5kX2Z1bmN0aW9uLGRmID0gZml0cy5ub24uc2VhcmNoLlJMTVtpXVtbMV1dLA0KICAgICAgICAgZGYyID0gZGZfbmFtZXNbaV1bWzFdXSkNCiAgfQ0KKQ0KDQpjb2VmLm5vbi5zZWFyY2guUkxNIDwtIGxhcHBseSgNCiAgMTpsZW5ndGgoZGZfbmFtZXMpLA0KICBmdW5jdGlvbiAoaSl7DQogIGJlc3QuaW5kLm5vbi5zZWFyY2guUkxNW2ldW1sxXV0gJT4lIGJpbmRfcm93cw0KICB9DQopICU+JQ0KICBiaW5kX3Jvd3MoKSAlPiUgDQogIGFzLmRhdGEuZnJhbWUoKSAlPiUgDQogIG11dGF0ZSgNCiAgICBjb3N0X3AyID0gMCwNCiAgICBsYW1iZGEgPSAwLA0KICAgIGFscGhhID0gMCwNCiAgICBwb3dlcnMyID0gMA0KICApICU+JSANCiAgc2VsZWN0KG9uZV9vZihjb2xuYW1lcyhjb2VmLjJfbWF0cml4KSkpDQoNCg0KYmVzdC5maXQubm9uLnNlYXJjaC5STE0gPC0gbGFwcGx5KDE6bGVuZ3RoKGRmX25hbWVzKSwNCiAgICAgIGZ1bmN0aW9uKGopIHsNCmxhcHBseSgxOmxlbmd0aChiZXN0LmluZC5ub24uc2VhcmNoLlJMTVtbal1dKSwNCiAgICAgIGZ1bmN0aW9uKGkpew0KICAgICAgICBiZXN0LmluZC5ub24uc2VhcmNoLlJMTVtqXVtbMV1dW2ldICU+JSANCiAgICAgICAgc2V0X25hbWVzKG5tID0gYmVzdC5pbmQubm9uLnNlYXJjaC5STE1bal1bWzFdXVtbaV1dWyJtb2RlbCJdKQ0KICAgICAgfSANCikNCiAgICAgIH0NCiAgICAgICApDQoNCg0KICANCmBgYA0KDQoNCmBgYHtyfQ0KDQotY29tYmluZWRfcmlkZ2VfdGltZStjb21iaW5lZF9ybG1fdGltZQ0KDQpgYGANCg0KDQpgYGB7ciwgd2FybmluZyA9IEZBTFNFfQ0KDQpncmFwaC5saXN0LnJsbSA8LSBsYXBwbHkoMTpsZW5ndGgoZGZfbmFtZXMpLA0KICAgICAgZnVuY3Rpb24oaSl7DQogICAgICBsYXBwbHkoMTpsZW5ndGgoYmVzdC5maXQubm9uLnNlYXJjaC5STE1baV1bWzFdXSksIGdyYXBoaW5nX2Z1bmN0aW9uX3JsbSwgZGYxPSBiZXN0LmZpdC5ub24uc2VhcmNoLlJMTVtpXSxkZjIgPSBkZl9uYW1lc1tpXSkNCiAgICAgIH0gDQopDQoNCg0KZ3JhcGgubGlzdC5SSURHRV9MQVNTTyA8LSBsYXBwbHkoMTpsZW5ndGgoZGZfbmFtZXMpLA0KICAgICAgZnVuY3Rpb24oaSl7DQogICAgICBsYXBwbHkoMTpsZW5ndGgoYmVzdC5maXQubm9uLnNlYXJjaC5SSURHRV9MQVNTT1tpXVtbMV1dKSwgZ3JhcGhpbmdfZnVuY3Rpb25fZWxhc3RpY25ldCwgZGYxPSBiZXN0LmZpdC5ub24uc2VhcmNoLlJJREdFX0xBU1NPW2ldLGRmMiA9IGRmX25hbWVzW2ldKQ0KICAgICAgfSANCikNCg0KDQoNCg0KYGBgDQoNCg0KIyMjIEV4cG9ydCBhbGwgUGxvdHMNCg0KYGBge3J9DQoNCmZvbGRlcl9uYW1lMSA8LSBwYXN0ZTAoIk91dHB1dC8iLCAib3V0cHV0ZmlsZXNfIiwgU3lzLkRhdGUoKSwgIl8iLCAiUkxNIiwgIi8iKQ0KZGlyLmNyZWF0ZShmb2xkZXJfbmFtZTEpICMgaXQgd2lsbCB0aHJvdyBhIHdhcm5pbmcgaWYgZm9sZGVyIGV4aXN0cw0KDQpsYXBwbHkoMTpsZW5ndGgoZGZfbmFtZXMpLA0KICAgICAgZnVuY3Rpb24oaikgew0KbGFwcGx5KDE6bGVuZ3RoKGRmX25hbWVzW1tqXV0pLGV4cG9ydF9ycGxvdHNfZnVuY3Rpb24yLHN0YXJ0aW5nX25hbWUgPSAiTm9uX1NlYXJjaF8iLGZvbGRlcl9uYW1lID0gZm9sZGVyX25hbWUxLGRmX2xpc3QgPSBkZl9uYW1lc1tbal1dLGdyYXBoaW5nX2xpc3QgPSBncmFwaC5saXN0LnJsbVtqXVtbMV1dKQ0KICAgICAgfQ0KICAgICAgICkNCg0KZm9sZGVyX25hbWUyIDwtIHBhc3RlMCgiT3V0cHV0LyIsICJvdXRwdXRmaWxlc18iLCBTeXMuRGF0ZSgpLCAiXyIsICJFbGFzdGljTmV0IiwgIi8iKQ0KZGlyLmNyZWF0ZShmb2xkZXJfbmFtZTIpICMgaXQgd2lsbCB0aHJvdyBhIHdhcm5pbmcgaWYgZm9sZGVyIGV4aXN0cw0KDQoNCmxhcHBseSgxOmxlbmd0aChkZl9uYW1lcyksDQogICAgICBmdW5jdGlvbihqKSB7DQpsYXBwbHkoMTpsZW5ndGgoZGZfbmFtZXNbW2pdXSksZXhwb3J0X3JwbG90c19mdW5jdGlvbjIsc3RhcnRpbmdfbmFtZSA9ICJOb25fU2VhcmNoXyIsZm9sZGVyX25hbWUgPSBmb2xkZXJfbmFtZTIsZGZfbGlzdCA9IGRmX25hbWVzW1tqXV0sZ3JhcGhpbmdfbGlzdCA9IGdyYXBoLmxpc3QuUklER0VfTEFTU09bal1bWzFdXSkNCiAgICAgIH0NCiAgICAgICApDQoNCmBgYA0KDQojIyMgU2hvdyBHcmFwaHMNCg0KYGBge3J9DQpsYXBwbHkoMTpsZW5ndGgoZGZfbmFtZXMpLA0KZnVuY3Rpb24oail7DQogIHN1YnBsb3QoZ3JhcGgubGlzdC5ybG1bal1bWzFdXSwgbnJvd3MgPSBsZW5ndGgoZ3JhcGgubGlzdC5ybG1bal1bWzFdXSkpDQp9DQopDQoNCg0KbGFwcGx5KDE6bGVuZ3RoKGRmX25hbWVzKSwNCmZ1bmN0aW9uKGkpew0KI3AxID0gZ3JhcGhfbmFtZXNbaV1bWzFdXQ0KZG8uY2FsbChncmlkLmFycmFuZ2UsZ3JhcGgubGlzdC5ybG1baV1bWzFdXSkNCiNyZXR1cm4oZ3JpZC5hcnJhbmdlKGdyb2JzID0gcDEpKQ0KfQ0KKQ0KDQoNCg0KYGBgDQoNCmBgYHtyfQ0KbGFwcGx5KDE6bGVuZ3RoKGRmX25hbWVzKSwNCmZ1bmN0aW9uKGopew0KICBzdWJwbG90KGdyYXBoLmxpc3QuUklER0VfTEFTU09bal1bWzFdXSwgbnJvd3MgPSBsZW5ndGgoZ3JhcGgubGlzdC5SSURHRV9MQVNTT1tqXVtbMV1dKSkNCn0NCikNCg0KDQpsYXBwbHkoMTpsZW5ndGgoZGZfbmFtZXMpLA0KZnVuY3Rpb24oaSl7DQojcDEgPSBncmFwaF9uYW1lc1tpXVtbMV1dDQpkby5jYWxsKGdyaWQuYXJyYW5nZSxncmFwaC5saXN0LlJJREdFX0xBU1NPW2ldW1sxXV0pDQojcmV0dXJuKGdyaWQuYXJyYW5nZShncm9icyA9IHAxKSkNCn0NCikNCg0KYGBgDQoNCg0K